package com.autumn.zero.file.storage.application.services.impl;

import java.util.List;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.autumn.util.ByteUtils;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.StringUtils;
import com.autumn.zero.file.storage.application.dto.FullFileInput;
import com.autumn.zero.file.storage.application.dto.FileInput;
import com.autumn.zero.file.storage.application.dto.FileUploadAttachmentOutput;
import com.autumn.zero.file.storage.application.dto.FileUploadIdInput;
import com.autumn.zero.file.storage.application.dto.FileUploadIdentificationInput;
import com.autumn.zero.file.storage.application.services.IFileUploadAppService;
import com.autumn.zero.file.storage.application.services.IFileUploadManager;
import com.autumn.zero.file.storage.services.IFileAttachmentInformationService;
import com.autumn.zero.file.storage.services.vo.FileAttachmentInformationRequest;
import com.autumn.zero.file.storage.services.vo.FileAttachmentInformationResponse;

/**
 * 文件上传管理
 * 
 * @author 老码农 2019-03-18 18:21:34
 */
public class FileUploadManagerImpl implements IFileUploadManager {

	@Autowired
	private IFileAttachmentInformationService fileService;

	@Override
	public final IFileAttachmentInformationService getFileService() {
		return this.fileService;
	}

	@Override
	public FileAttachmentInformationResponse saveUploadFile(FullFileInput input) throws Exception {
		ExceptionUtils.checkNotNull(input, "input");
		input.valid();
		if (input.getOriginalFileSize() != null && input.getOriginalFileSize() > 0 && input.getLimitSize() != null
				&& input.getLimitSize() > 0 && input.getOriginalFileSize() > input.getLimitSize()) {
			IOUtils.closeQuietly(input.getInputStream());
			ExceptionUtils
					.throwValidationException("上传文件太大，超过限制大小[" + ByteUtils.getFileSize(input.getLimitSize()) + "]");
		}
		input.setUrlPath(StringUtils.removeStart(StringUtils.removeEnd(input.getUrlPath(), '/'), '/'));
		FileAttachmentInformationRequest request = new FileAttachmentInformationRequest(input.getFileAttachmentType(),
				input.getUrlPath(), input.getOriginalFilename(), input.getInputStream());
		if (input.getLimitExtensions() != null && input.getLimitExtensions().size() > 0
				&& !input.getLimitExtensions().contains("*")) {
			if (StringUtils.isNullOrBlank(request.getExtensionName())
					|| !input.getLimitExtensions().contains(request.getExtensionName())) {
				IOUtils.closeQuietly(input.getInputStream());
				ExceptionUtils.throwValidationException("上传的文件类型不支持。");
			}
		}
		request.setModuleName(input.getModuleName());
		return fileService.saveUploadFile(request);
	}

	@Override
	public FileAttachmentInformationResponse saveUploadFile(IFileUploadAppService service, FileInput input,
			String currentUrlPath) throws Exception {
		ExceptionUtils.checkNotNull(input, "input");
		input.valid();
		if (service == null) {
			IOUtils.closeQuietly(input.getInputStream());
			ExceptionUtils.throwValidationException("应用服务不能为 null。");
		}
		FullFileInput fuleInput = new FullFileInput();
		fuleInput.setFileAttachmentType(service.getFileUploadAttachmentType());
		fuleInput.setInputStream(input.getInputStream());
		fuleInput.setLimitExtensions(service.getFileUploadLimitExtensions());
		fuleInput.setLimitSize(service.getFileUploadLimitSize());
		fuleInput.setOriginalFilename(input.getOriginalFilename());
		fuleInput.setOriginalFileSize(input.getOriginalFileSize());
		fuleInput.setModuleName(service.getModuleName());
		String url;
		if (StringUtils.isNullOrBlank(currentUrlPath)) {
			url = StringUtils.removeStart(service.getFileUploadStartPath(), '/');
		} else {
			url = StringUtils.removeEnd(service.getFileUploadStartPath(), '/') + "/"
					+ StringUtils.removeStart(currentUrlPath, '/');
		}
		fuleInput.setUrlPath(url);
		return this.saveUploadFile(fuleInput);
	}

	@Override
	public List<FileAttachmentInformationResponse> useUploadFiles(IFileUploadAppService service, Long targetId,
			Object fileUploadInput) {
		List<FileAttachmentInformationResponse> uploadFiles;
		if (fileUploadInput instanceof FileUploadIdentificationInput) {
			FileUploadIdentificationInput identificationInput = (FileUploadIdentificationInput) fileUploadInput;
			uploadFiles = this.getFileService().useUploadFileByIdentification(service.getFileUploadAttachmentType(),
					targetId, identificationInput.getUploadFiles());
		} else if (fileUploadInput instanceof FileUploadIdInput) {
			FileUploadIdInput idInput = (FileUploadIdInput) fileUploadInput;
			uploadFiles = this.getFileService().useUploadFile(service.getFileUploadAttachmentType(), targetId,
					idInput.getUploadFileIds());
		} else {
			throw ExceptionUtils.throwValidationException(
					"fileUploadInput 对象未实现 FileUploadIdentificationInput 或  UploadFileIdInput 接口。");
		}
		return uploadFiles;
	}

	@Override
	public void loadUploadFileOutput(List<FileAttachmentInformationResponse> uploadFiles, Object fileUploadOutput) {
		if (fileUploadOutput != null && fileUploadOutput instanceof FileUploadAttachmentOutput) {
			FileUploadAttachmentOutput fileOutput = (FileUploadAttachmentOutput) fileUploadOutput;
			fileOutput.setUploadFiles(uploadFiles);
		}
	}

	@Override
	public void loadUploadFileOutput(IFileUploadAppService service, Long targetId, Object fileUploadOutput) {
		if (fileUploadOutput != null && fileUploadOutput instanceof FileUploadAttachmentOutput) {
			List<FileAttachmentInformationResponse> uploadFiles = this.getFileService()
					.queryByTargetList(service.getFileUploadAttachmentType(), targetId);
			this.loadUploadFileOutput(uploadFiles, fileUploadOutput);
		}
	}

	@Override
	public void deleteUploadFiles(IFileUploadAppService service, Long targetId) {
		this.getFileService().deleteByTarget(service.getFileUploadAttachmentType(), targetId);
	}

}
